#include "imagenes.h"

void Imagen::abrirImagen()
{
	string buffer;
	fstream fpgm(_nombre.c_str());
	if(fpgm.good())
	{
		fpgm>>_encabezado;//el tipo de pgm en este caso P2
		fpgm>>buffer;//saco y veo si es un #
		if(buffer=="#")
		{
			getline(fpgm,buffer);//la linea que le sigue al #
			fpgm>>buffer;//la cant de columnas
		}
		_columnas = atoi(buffer.c_str());
		fpgm>>buffer;//la cant de filas
		_filas = atoi(buffer.c_str());
		fpgm>>buffer;//el maximo valor que aparece en la matriz
		_maxValor=atoi(buffer.c_str());
		
		_laImagen = new Matriz(_filas,_columnas);
		double valor;
		
		for(Indice i=1;i<=_filas;i++)
			for(Indice j=1;j<=_columnas;j++)
			{
				fpgm>>buffer;
				valor = atof(buffer.c_str());
				_laImagen->set(i,j,valor);
			}
	}
	fpgm.close();
}

void Imagen::armarImagen(Matriz* m)
{
	ofstream fpgm(("comprimida"+_nombre).c_str());
	if(fpgm.good())
	{
		fpgm<<_encabezado<<endl<<_columnas<<" "<<_filas<<endl<<_maxValor<<endl;
		for(Indice i=1;i<=_filas;i++)
			for(Indice j=1;j<=_columnas;j++)
				fpgm<<m->get(i,j)<<endl;
	}
	fpgm.close();
}

Imagen::Imagen(string archivoImg,int calidad)
{
	_laImagen=NULL;
	_laImagenComprimida=NULL;
	_calidad=calidad;
	_nombre=archivoImg;
	this->abrirImagen();
}

Matriz* Imagen::dameLaMatrizDeLaImagen()
{
	return _laImagen;
}

//matSigma es un vector que tiene los elementos de la digonal
//la matV asume que no viene traspuesta
void Imagen::guardarDatos(Matriz* matU,Matriz* matV,Matriz* matSigma)
{
	_laImagenComprimida=new Matriz(_filas,_columnas);
	double coef;
	for(Tam i=1;i<=_filas;i++)
		for(Tam j=1;j<=_calidad;j++)
			_laImagenComprimida->set(i,j,matU->get(i,j)*matSigma->get(j,1));
	
	Matriz *temp=new Matriz(_filas,_columnas);
	temp->copiarMatriz(_laImagen);
	for(Tam i=1;i<=_filas;i++)
		for(Tam j=1;j<=_columnas;j++)
		{
			coef=0;
			for(Tam k=1;k<=_calidad;k++)
				coef+=temp->get(i,k)*matV->get(k,j);
			_laImagenComprimida->set(i,j,coef);
		}
	armarImagen(_laImagenComprimida);
}

void Imagen::reconstruirLaImagen(Matriz* mat)
{
	armarImagen(mat);
}

Tam Imagen::filasDeLaImagen()const
{
	return _filas;
}

Tam Imagen::columnasDeLaImage()const
{
	return _columnas;
}

double Imagen::errorCuadraticoMedio()
{
	double ret=0;
	for(Tam i=1;i<=_filas;i++)
		for(Tam j=1;j<=_columnas;j++)
			ret+=pow(_laImagen->get(i,j) - _laImagenComprimida->get(i,j),2);
	return ret/(_filas*_columnas);
}

Imagen::~Imagen()
{
	delete _laImagen;
	delete _laImagenComprimida;
}
